package com.ccys.cms.service.masterData.impl;

import cn.hutool.core.util.ObjectUtil;
import com.ccys.cms.service.masterData.CountryService;
import com.ccys.common.vo.ResponseResult;
import com.ccys.db.dto.masterData.*;
import com.ccys.db.entity.TblCountry;
import com.ccys.db.entity.TblCountryServiceType;
import com.ccys.db.entity.TblCountryServiceTypeProfileType;
import com.ccys.db.enums.CountryServiceTypeEnum;
import com.ccys.db.enums.CountryServiceTypeProfileTypeEnum;
import com.ccys.db.mapper.TblCountryMapper;
import com.ccys.db.mapper.TblCountryServiceTypeMapper;
import com.ccys.db.mapper.TblCountryServiceTypeProfileTypeMapper;
import com.ccys.db.page.PageDto;
import com.ccys.db.rely.service.impl.BaseServiceImpl;
import com.ccys.db.vo.masterData.CountryListVo;
import com.ccys.db.vo.masterData.CountryPageQueryVo;
import com.ccys.db.vo.masterData.CountryServiceTypeAndProfileTypeVo;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @program: WhiteCoat
 * @description: 国家实现类
 * @author: ZhangJingCan
 * @create: 2023-12-13 11:26
 **/

@Service
public class CountryServiceImpl extends BaseServiceImpl<TblCountry> implements CountryService {

    /**
     * 国家
     */
    @Resource
    private TblCountryMapper tblCountryMapper;

    /**
     * 国家服务设置
     */
    @Resource
    private TblCountryServiceTypeMapper tblCountryServiceTypeMapper;

    /**
     * 国家服务设置详情
     */
    @Resource
    private TblCountryServiceTypeProfileTypeMapper tblCountryServiceTypeProfileTypeMapper;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult saveCountry(CountrySaveDto dto) {
        //无论新增还是修改都需要校验几个必传字段
        if (ObjectUtil.isEmpty(dto.getName()) || ObjectUtil.isEmpty(dto.getIso())
                || ObjectUtil.isEmpty(dto.getIso3()) || ObjectUtil.isEmpty(dto.getDial())) {
            return ResponseResult.error("Parameter Error!");
        }
        //校验是否存在 - 如果ID也有值 - 则需要排除自身
        Example example = new Example(TblCountry.class);
        Example.Criteria criteria = example.createCriteria().andEqualTo("name", dto.getName()).andEqualTo("delFlag", 0);
        if (ObjectUtil.isNotEmpty(dto.getId())) {
            criteria.andNotEqualTo("id", dto.getId());
        }
        //判断 - 如果存在则返回错误信息
        if (ObjectUtil.isNotEmpty(tblCountryMapper.selectOneByExample(example))) {
            return ResponseResult.error("This country's data already exists!");
        }

        //判断是新增还是修改？
        if (ObjectUtil.isEmpty(dto.getId())) {
            //新增 - 新增需要同时生成 - 六个设置 - 以及设置里面的详情数据
            if (tblCountryMapper.insertSelective(dto) > 0) {
                //准备国家服务设置数据 - 共六条
                List<Integer> profileTypeIds = new ArrayList<>();
                profileTypeIds.add(CountryServiceTypeProfileTypeEnum.SELF.getCode());
                profileTypeIds.add(CountryServiceTypeProfileTypeEnum.AIA_CORPORATE_INSURANCE.getCode());
                profileTypeIds.add(CountryServiceTypeProfileTypeEnum.AIA_HELTHSHIELD.getCode());
                profileTypeIds.add(CountryServiceTypeProfileTypeEnum.CORPORATE_SCHEME.getCode());
                profileTypeIds.add(CountryServiceTypeProfileTypeEnum.WHITECOAT_TELEHEALTH_FAMILY_PLAN.getCode());
                profileTypeIds.add(CountryServiceTypeProfileTypeEnum.CDMP_PROGRAMMES.getCode());

                //gp
                addServiceTypeAndAddProfileType(dto.getId(), CountryServiceTypeEnum.PRACTITIONER.getCode(), profileTypeIds);

                //paediatrician
                addServiceTypeAndAddProfileType(dto.getId(), CountryServiceTypeEnum.PAEDIATRICIAN.getCode(), profileTypeIds);

                //mental_wellness
                addServiceTypeAndAddProfileType(dto.getId(), CountryServiceTypeEnum.MENTAL_WELLNESS.getCode(), profileTypeIds);

                //obstetrics_and_gynaecology
                addServiceTypeAndAddProfileType(dto.getId(), CountryServiceTypeEnum.OBSTETRISC_AND_GYNAECOLOGY.getCode(), profileTypeIds);

                //Think_well
                addServiceTypeAndAddProfileType(dto.getId(), CountryServiceTypeEnum.THINK_WELL.getCode(), null);

                //home_based_health_screening
                addServiceTypeAndAddProfileType(dto.getId(), CountryServiceTypeEnum.HOME_BASED_HEALTH_SCREENING.getCode(), null);
                return ResponseResult.success("Added successfully!");
            } else {
                //添加失败的返回
                return ResponseResult.error("Failed to add data!");
            }
        } else {
            //修改 - 这里的修改只修改当前表的 - 根据主键修改不为null的值
            tblCountryMapper.updateByPrimaryKeySelective(dto);
            return ResponseResult.success("Failed to modify country data!");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult deleteCountry(CountryIdDto dto) {
        //校验参数
        if (ObjectUtil.isEmpty(dto.getId())) {
            return ResponseResult.error("Parameter Error!");
        }
        //准备参数进行软删除 - 国家
        TblCountry country = new TblCountry();
        country.setId(dto.getId());
        country.setDelFlag(1);

        //国家设置
        TblCountryServiceType serviceType = new TblCountryServiceType();
        serviceType.setCountryId(dto.getId());
        serviceType.setDelFlag(1);

        //国家设置详情
        TblCountryServiceTypeProfileType profileType = new TblCountryServiceTypeProfileType();
        profileType.setCountryId(dto.getId());
        profileType.setDelFlag(1);

        //进行操作并返回是否成功
        if (tblCountryMapper.updateByPrimaryKeySelective(country) > 0
                && tblCountryServiceTypeMapper.updateByPrimaryKeySelective(serviceType) > 0
                && tblCountryServiceTypeProfileTypeMapper.updateByPrimaryKeySelective(profileType) > 0) {
            return ResponseResult.success("Delete Successful!");
        }
        throw new RuntimeException("Error deleting country data!");
    }

    @Override
    public ResponseResult<PageInfo<CountryPageQueryVo>, Object> findPageCountry(CountryPageQueryDto dto) {
        //这里只查本表以及tbl_account表
        PageDto.startPage();
        PageInfo<CountryPageQueryVo> info = new PageInfo<>(tblCountryMapper.findPage(dto));
        return ResponseResult.success(info);
    }

    @Override
    public ResponseResult findListServiceTypeAndProfileTypeByCountryId(CountryIdDto dto) {
        if (ObjectUtil.isEmpty(dto.getId())) {
            return ResponseResult.error("Parameter Error!");
        }
        //查询当前国家是否未删除
        Example example = new Example(TblCountry.class);
        example.createCriteria().andEqualTo("id", dto.getId()).andEqualTo("delFlag", 0);
        if (ObjectUtil.isEmpty(tblCountryMapper.selectOneByExample(example))) {
            return ResponseResult.error("illegal request!");
        }
        Example serviceType = new Example(TblCountryServiceType.class);
        serviceType.createCriteria().andEqualTo("countryId", dto.getId()).andEqualTo("delFlag", 0);
        List<TblCountryServiceType> serviceTypes = tblCountryServiceTypeMapper.selectByExample(serviceType);
        if (ObjectUtil.isEmpty(serviceTypes)) {
            return ResponseResult.error("System data error!");
        }
        //用流的方式同名复制
        List<CountryServiceTypeAndProfileTypeVo> collect = serviceTypes.stream().map(service -> {
            CountryServiceTypeAndProfileTypeVo vo = new CountryServiceTypeAndProfileTypeVo();
            BeanUtils.copyProperties(service, vo);
            return vo;
        }).collect(Collectors.toList());

        //查询详情表数据
        Example profileType = new Example(TblCountryServiceTypeProfileType.class);
        profileType.createCriteria().andEqualTo("countryId", dto.getId()).andEqualTo("delFlag", 0);
        List<TblCountryServiceTypeProfileType> list = tblCountryServiceTypeProfileTypeMapper.selectByExample(profileType);
        if (ObjectUtil.isEmpty(list)) {
            return ResponseResult.error("System data error!");
        }

        //流的方式根据type分组
        Map<Integer, List<TblCountryServiceTypeProfileType>> map = list.stream().collect(Collectors.groupingBy(TblCountryServiceTypeProfileType::getServiceType));

        //组装数据 - 并且根据type去找详情集合
        for (CountryServiceTypeAndProfileTypeVo vo : collect) {
            vo.setList(map.get(vo.getServiceType()));
        }
        //返回最终组装好的数据
        return ResponseResult.success(collect);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult updateServiceType(CountryServiceTypeDto dto) {
        if (ObjectUtil.isEmpty(dto.getId())) {
            return ResponseResult.error("Parameter Error!");
        }
        //同名复制
        TblCountryServiceType tblCountryServiceType = new TblCountryServiceType();
        BeanUtils.copyProperties(dto, tblCountryServiceType);
        if (tblCountryServiceTypeMapper.updateByPrimaryKeySelective(tblCountryServiceType) > 0) {
            return ResponseResult.success("Modified successfully!");
        }
        return ResponseResult.error("Modification failed!");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult updateCountryServiceTypeProfileType(CountryServiceTypeProfileTypeDto dto) {
        if (ObjectUtil.isEmpty(dto.getId())) {
            return ResponseResult.error("Parameter Error!");
        }
        TblCountryServiceTypeProfileType type = new TblCountryServiceTypeProfileType();
        BeanUtils.copyProperties(dto, type);
        //操作数据库 - 这个方法只会修改有值的字段
        if (tblCountryServiceTypeProfileTypeMapper.updateByPrimaryKeySelective(type) > 0) {
            return ResponseResult.success("Modified successfully!");
        }
        return ResponseResult.error("Modification failed!");
    }

    @Override
    public ResponseResult<List<CountryListVo>, Object> findList() {
        List<CountryListVo> list = tblCountryMapper.findList();
        return ResponseResult.success(list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult countrySetDoc(CountrySetDocDto dto) {
        if (ObjectUtil.isEmpty(dto.getId())) {
            return ResponseResult.error("Parameter abnormality");
        }
        TblCountry country = tblCountryMapper.findById(dto.getId());
        if (ObjectUtil.isEmpty(country)) {
            return ResponseResult.error("Data does not exist");
        }
        BeanUtils.copyProperties(dto, country);
        //只会修改不为null的字段 - 上方就算未传入某些字段 country的某些字段被赋值为null值也无所谓
        if (tblCountryMapper.updateByPrimaryKeySelective(country) > 0) {
            return ResponseResult.success("Operation successful");
        }
        return ResponseResult.error("operation failed");
    }


    /**
     * 根据传入的国家ID和类型生成 - 国家设置 - 国家设置详情数据
     *
     * @param countryId
     * @param serviceType
     * @param profileTypeIds
     */
    @Transactional(rollbackFor = Exception.class)
    public void addServiceTypeAndAddProfileType(String countryId, Integer serviceType, List<Integer> profileTypeIds) {
        TblCountryServiceType tblCountryServiceType = new TblCountryServiceType();
        tblCountryServiceType.setCountryId(countryId);
        tblCountryServiceType.setIsShowHomepage(1);
        tblCountryServiceType.setIsOpenWebview(1);
        tblCountryServiceType.setIsAllowTextBased(1);
        tblCountryServiceType.setOnDemandDisplay("Dynamic");
        tblCountryServiceType.setIsDisableService(1);
        tblCountryServiceType.setIsDisableServiceNonRetail(1);
        tblCountryServiceType.setServiceType(serviceType);
        if (serviceType.equals(CountryServiceTypeEnum.THINK_WELL.getCode())) {
            tblCountryServiceType.setIsDisableService(null);
            tblCountryServiceType.setIsDisableServiceNonRetail(null);
        } else if (serviceType.equals(CountryServiceTypeEnum.HOME_BASED_HEALTH_SCREENING.getCode())) {
            tblCountryServiceType.setIsDisableService(null);
            tblCountryServiceType.setIsDisableServiceNonRetail(null);
            tblCountryServiceType.setOnDemandDisplay(null);
        }
        //保存国家设置
        tblCountryServiceTypeMapper.insertSelective(tblCountryServiceType);

        //国家详情
        if (ObjectUtil.isNotEmpty(profileTypeIds)) {
            for (Integer i : profileTypeIds) {
                TblCountryServiceTypeProfileType type = new TblCountryServiceTypeProfileType();
                type.setCountryId(countryId);
                type.setServiceType(serviceType);
                type.setMemberProfileTypeId(i);
                type.setProfileTypeName(CountryServiceTypeProfileTypeEnum.getMessageByCode(i));
                //serviceType=1并且memberProfileTypeId=4的时候才给 subscription_package_id 设置值，现在不知道设置什么值
                //2024-01-05 回复：设置00000000-0000-0000-0000-000000000000，应该是用不上了
                if (1 == serviceType && 4 == i) {
                    type.setSubscriptionPackageId("00000000-0000-0000-0000-000000000000");
                }
                type.setIsShow(1);
                type.setIsVideo(1);
                type.setIsInClinic(1);
                type.setIsTextBased(1);
                //保存国家设置详情
                tblCountryServiceTypeProfileTypeMapper.insertSelective(type);
            }
        }
    }
}
